package com.sychip.fhc.app.wsn.screen.components

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.material3.MaterialTheme.colorScheme
import androidx.compose.material3.OutlinedTextFieldDefaults
import androidx.compose.material3.Switch
import androidx.compose.material3.SwitchDefaults
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.fhc.base.EventBusSubGInfo
import com.fhc.base.LocalManager.stringResource
import com.fhc.view.FhcComoBox
import com.fhc.view.KeyLabel
import com.fhc.view.rememberFhcComoBoxState
import com.sychip.fhc.app.todo.R
import com.sychip.fhc.app.wsn.common.ChannelList
import com.sychip.fhc.app.wsn.screen.HexInputField
import timber.log.Timber

enum class SubGSettingCmd {
    NULL,
    INIT,
    RESET,
    SAVE,
}

val HEX_PAN_PORT_PATTERN = "^[0-9a-fA-F]{4}$".toRegex()
val HEX_KEY_REGEX = "^[a-fA-F0-9]{32}$".toRegex()
val ALL_ZERO_KEY = "00000000000000000000000000000000"

@Preview(showBackground = true)
@Composable
fun SubGSettingView(subGInfo: MutableState<EventBusSubGInfo> = mutableStateOf(EventBusSubGInfo()),
                    subGCmd: MutableState<SubGSettingCmd> = mutableStateOf( SubGSettingCmd.NULL),
                    onInit:()->Boolean = {true},
                    onSave: (EventBusSubGInfo, Boolean) -> Boolean = { _, _ -> true },
                    onReset:()->Boolean = {true},
) {

    val tempSubG by remember { mutableStateOf(subGInfo.value) }
    val currentCmd by remember { subGCmd }

    val encryptionState = remember { mutableStateOf(tempSubG.encryption) }
    val keyState = remember { mutableStateOf(tempSubG.key) }
    if(!encryptionState.value) {
        keyState.value = ALL_ZERO_KEY
        tempSubG.key = keyState.value
    }

    var isKeyError by remember { mutableStateOf(false) }
    isKeyError = tempSubG.encryption && ( !tempSubG.key.matches(HEX_KEY_REGEX) || tempSubG.key == ALL_ZERO_KEY)
    val errMsgKey = stringResource(R.string.wsn_subg_key_rule)

    val mChannelOptions = remember {
        mutableStateOf(ChannelList)
    }
    val mChannelCtry = remember {
        mutableStateOf(listOf(KeyLabel("JPN","JPN")))
    }

    val mChannelOptionKL: MutableState<KeyLabel?> = rememberFhcComoBoxState()
    mChannelOptionKL.value = mChannelOptions.value[0]
    mChannelOptions.value.forEachIndexed { index, label ->
        if(!tempSubG.channel.isEmpty() && label.key == tempSubG.channel.toInt(16)) {
            mChannelOptionKL.value = label
        }
    }
    val myInt =  mChannelOptionKL.value!!.key as Int
    tempSubG.channel = String.format("%02X", myInt)

    val mChannelCtryKL = rememberFhcComoBoxState()
    mChannelCtryKL.value = mChannelCtry.value[0]


    val panIdState = remember { mutableStateOf(tempSubG.panId) }
    // PAN ID 验证函数
    fun isValidPanPort(panId: String, isPan: Boolean = true): Boolean {
        if (!panId.matches(HEX_PAN_PORT_PATTERN)) return false

        return try {
            val hexValue = panId.toInt(16)
            hexValue in if(isPan) 0x0000..0xFFFE else 0x1010..0x137E
        } catch (_: NumberFormatException) {
            false
        }
    }
    var isPanIdError by remember { mutableStateOf(false) }
    isPanIdError = !isValidPanPort(tempSubG.panId)
    val errMsgPanId = stringResource(R.string.wsn_subg_pan_rule)




    val portState = remember { mutableStateOf(tempSubG.port) }
    var isPortError by remember { mutableStateOf(false) }
    isPortError = !isValidPanPort(tempSubG.port, false)
    val errMsgPort = stringResource(R.string.wsn_subg_port_rule)




    val borderColor = colorResource(id = android.R.color.darker_gray)
    val errorColor = colorScheme.error
    Column(modifier = Modifier.fillMaxWidth().wrapContentHeight().padding(bottom = 60.dp),
        verticalArrangement = Arrangement.spacedBy(8.dp), // 设置垂直间距
        horizontalAlignment = Alignment.CenterHorizontally // 设置水平对齐方式
    ) {
        Row(
            modifier = Modifier.padding(start = 16.dp, end = 16.dp, top = 5.dp).fillMaxWidth(),
            verticalAlignment = Alignment.CenterVertically,
            horizontalArrangement = Arrangement.SpaceBetween,
        ) {
            Text(modifier = Modifier.wrapContentSize().padding(end = 5.dp),text = stringResource(R.string.wsn_subg_encryption))
            Switch(
                modifier = Modifier.wrapContentSize().padding(5.dp),
                checked = encryptionState.value,
                onCheckedChange = {
                    encryptionState.value = it
                    tempSubG.encryption =  encryptionState.value  // 同步更新
                    if(!encryptionState.value) {
                        keyState.value = ALL_ZERO_KEY
                    }else{
                        keyState.value = ""
                    }
                    tempSubG.key = keyState.value
                },
                colors = SwitchDefaults.colors(
                    checkedTrackColor = colorScheme.primary
                )
            )

            HexInputField(
                modifier = Modifier.fillMaxWidth().weight(1f),
                value = keyState.value,
                prefix = "",
                enabled = tempSubG.encryption ,
                maxLength = 32,
                onValueChange = { newValue ->
//                    val filteredValue = newValue.uppercase().filter { it in '0'..'9'|| it in 'A'..'F' }
//                    keyState.value = filteredValue.take(32)
                    keyState.value = newValue
                    tempSubG.key = keyState.value // 同步更新
                    isKeyError = tempSubG.encryption && ( !tempSubG.key.matches(HEX_KEY_REGEX) || tempSubG.key == ALL_ZERO_KEY)

                },
                label = stringResource(R.string.wsn_subg_key),
                isError = isKeyError,
                errorMessage = errMsgKey,
            )
        }

        Row(
            modifier = Modifier.padding(start = 16.dp, end = 16.dp, top = 5.dp).fillMaxWidth(),
            verticalAlignment = Alignment.CenterVertically,
            horizontalArrangement = Arrangement.spacedBy(8.dp),
        ) {
            FhcComoBox(
                modifier = Modifier.weight(5f),
                label = { Text(stringResource(R.string.wsn_subg_channel)) },
                selectedKeyLabel = mChannelOptionKL,
                onValueChange =  {idx->
                    val myInt =  mChannelOptions.value[idx].key as Int
                    tempSubG.channel = String.format("%02X", myInt)
                    mChannelOptionKL.value = mChannelOptions.value[idx]
                },
                colors =  OutlinedTextFieldDefaults.colors(
                    unfocusedContainerColor = Color.Transparent,
                    focusedContainerColor = Color.Transparent,
                    errorContainerColor = Color.Transparent,
                    focusedBorderColor = borderColor,
                    unfocusedBorderColor = borderColor,
                    errorBorderColor = errorColor,
                    disabledBorderColor = borderColor.copy(alpha = 0.3f),
                    cursorColor = colorScheme.primary
                ),
                items = mChannelOptions
            )

            FhcComoBox(
                modifier = Modifier.weight(3f),
                label = { Text(stringResource(R.string.wsn_subg_channel_country)) },
                selectedKeyLabel = mChannelCtryKL,
                onValueChange =  {it->
                    // TODO 这里只有一个country，若有多个需要验证
//                    _tempSubG.channel = "${it?.key}"
//                    mChannelCtryKL.value = mChannelCtry.value.find { it.key == _tempSubG.channel}
                },
                colors =  OutlinedTextFieldDefaults.colors(
                    unfocusedContainerColor = Color.Transparent,
                    focusedContainerColor = Color.Transparent,
                    errorContainerColor = Color.Transparent,
                    focusedBorderColor = borderColor,
                    unfocusedBorderColor = borderColor,
                    errorBorderColor = errorColor,
                    disabledBorderColor = borderColor.copy(alpha = 0.3f),
                    cursorColor = colorScheme.primary
                ),
                items = mChannelCtry
            )
        }


        Row(
            modifier = Modifier.padding(start = 16.dp, end = 16.dp, top = 5.dp).fillMaxWidth(),
            verticalAlignment = Alignment.CenterVertically,
            horizontalArrangement = Arrangement.spacedBy(8.dp)
        ) {
            HexInputField(
                modifier = Modifier.fillMaxWidth().weight(1f),
                value = panIdState.value,
                onValueChange = { newValue ->
                    panIdState.value = newValue
                    tempSubG.panId = panIdState.value
                    isPanIdError = !isValidPanPort(tempSubG.panId)
                },
                label = stringResource(R.string.wsn_subg_pan),
                isError = isPanIdError,
                errorMessage = errMsgPanId,
                maxLength = 4,
            )
            HexInputField(
                modifier = Modifier.fillMaxWidth().weight(1f),
                value = portState.value,
                onValueChange = { newValue ->
                    portState.value = newValue
                    tempSubG.port = portState.value
                    isPortError = !isValidPanPort(tempSubG.port, false)
                },
                label = stringResource(R.string.wsn_subg_port),
                isError = isPortError,
                errorMessage = errMsgPort,
                maxLength = 4,
                imeAction = ImeAction.Done,
            )
//
//            OutlinedTextField(
//                modifier = Modifier.fillMaxWidth().weight(1f),
//                value = portState.value,
//                onValueChange = {newValue->
//                    val filteredValue = newValue.uppercase().filter { it in '0'..'9' || it in 'A'..'F' }
//                    portState.value = filteredValue.take(4)
//                    _tempSubG.port = portState.value // 同步更新
//                    isPortError = !isValidPanPort(_tempSubG.port,false)
//                },
//                label = {
//                    Text(stringResource(R.string.wsn_subg_port), color = if (isPortError) errorColor else borderColor,)
//                },
//                isError = isPortError,
//                supportingText = {
//                    if (isPortError) {
//                        Text(text = errMsgPort, color = colorScheme.error)
//                    }
//                },
//                trailingIcon = {
//                    if (isPortError) {
//                        Icon(
//                            Icons.Filled.Error,
//                            "error",
//                            tint = colorScheme.error
//                        )
//                    }
//                },
//                keyboardOptions = KeyboardOptions(capitalization = KeyboardCapitalization.Characters,  // 强制大写
//                    autoCorrectEnabled = false,  // 禁用自动修正
//                    keyboardType = KeyboardType.Ascii,  // 或使用 KeyboardType.Password 隐藏输入内容
//                    imeAction = ImeAction.Done
//                ),
//                singleLine = true,
//                shape = MaterialTheme.shapes.extraSmall,
//                colors = OutlinedTextFieldDefaults.colors(
//                    unfocusedContainerColor = Color.Transparent,
//                    focusedContainerColor = Color.Transparent,
//                    errorContainerColor = Color.Transparent,
//                    focusedBorderColor = if (isPortError) errorColor else borderColor,
//                    unfocusedBorderColor = if (isPortError) errorColor else borderColor,
//                    errorBorderColor = errorColor,
//                    disabledBorderColor = if (isPortError) errorColor else borderColor.copy(alpha = 0.3f),
//                    cursorColor = if (isPortError) errorColor else colorScheme.primary
//                )
//            )
        }

    }



    LaunchedEffect(currentCmd){
        when(subGCmd.value) {
            SubGSettingCmd.NULL -> {

            }
            SubGSettingCmd.INIT -> {
                Timber.i("SubGSettingView   INIT: %s    %s", subGInfo.value.panId, subGInfo.value.port )

                onInit.invoke()
            }
            SubGSettingCmd.RESET -> {
                Timber.i("SubGSettingView   RESET: %s    %s", subGInfo.value.panId, subGInfo.value.port )

                onReset.invoke()
            }

            SubGSettingCmd.SAVE -> {
                Timber.i("SubGSettingView   SAVE: %s    %s", subGInfo.value.panId, subGInfo.value.port )
                subGCmd.value = SubGSettingCmd.NULL
                onSave.invoke(tempSubG, isPanIdError|| isPortError || isKeyError)
            }
        }
    }
}
